package com.ruoyi.system.service.impl;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Arrays;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.DayOfWeek;
import java.time.temporal.TemporalAdjusters;
import java.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.SyncDbSyncMapper;
import com.ruoyi.system.mapper.SyncDatabaseMapper;
import com.ruoyi.system.domain.datasync.SyncDbSync;
import com.ruoyi.system.domain.datasync.SyncDatabase;
import com.ruoyi.system.service.ISyncDbSyncService;
import com.ruoyi.system.service.ISyncDatabaseService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.datasync.SyncServer;
import com.ruoyi.system.domain.datasync.SyncLog;
import com.ruoyi.system.mapper.SyncServerMapper;
import com.ruoyi.system.mapper.SyncLogMapper;
import java.sql.DriverManager;

/**
 * 数据库同步Service业务层处理
 * 
 * @author ruoyi
 */
@Service
public class SyncDbSyncServiceImpl implements ISyncDbSyncService 
{
    @Autowired
    private SyncDbSyncMapper syncDbSyncMapper;
    
    @Autowired
    private SyncDatabaseMapper syncDatabaseMapper;

    @Autowired
    private SyncServerMapper syncServerMapper;

    @Autowired
    private SyncLogMapper syncLogMapper;

    @Autowired
    private ISyncDatabaseService syncDatabaseService;

    /**
     * 查询数据库同步
     * 
     * @param syncId 数据库同步主键
     * @return 数据库同步
     */
    @Override
    public SyncDbSync selectSyncDbSyncBySyncId(Long syncId)
    {
        return syncDbSyncMapper.selectSyncDbSyncBySyncId(syncId);
    }

    /**
     * 查询数据库同步列表
     * 
     * @param syncDbSync 数据库同步
     * @return 数据库同步
     */
    @Override
    public List<SyncDbSync> selectSyncDbSyncList(SyncDbSync syncDbSync)
    {
        return syncDbSyncMapper.selectSyncDbSyncList(syncDbSync);
    }

    /**
     * 新增数据库同步
     * 
     * @param syncDbSync 数据库同步
     * @return 结果
     */
    @Override
    public int insertSyncDbSync(SyncDbSync syncDbSync)
    {
        // 设置默认值
        if (syncDbSync.getStatus() == null) {
            syncDbSync.setStatus("0");
        }
        
        // 获取数据库名称和服务器名称
        if (syncDbSync.getSourceDbId() != null) {
            SyncDatabase sourceDb = syncDatabaseMapper.selectSyncDatabaseByDbId(syncDbSync.getSourceDbId());
            if (sourceDb != null) {
                syncDbSync.setSourceDbName(sourceDb.getDbName());
                
                // 获取服务器信息
                SyncServer sourceServer = syncServerMapper.selectSyncServerByServerId(sourceDb.getServerId());
                if (sourceServer != null) {
                    // 设置源数据库服务器名称
                    syncDbSync.setSourceServerName(sourceServer.getServerName());
                }
            }
        }
        
        if (syncDbSync.getTargetDbId() != null) {
            SyncDatabase targetDb = syncDatabaseMapper.selectSyncDatabaseByDbId(syncDbSync.getTargetDbId());
            if (targetDb != null) {
                syncDbSync.setTargetDbName(targetDb.getDbName());
                
                // 获取服务器信息
                SyncServer targetServer = syncServerMapper.selectSyncServerByServerId(targetDb.getServerId());
                if (targetServer != null) {
                    // 设置目标数据库服务器名称
                    syncDbSync.setTargetServerName(targetServer.getServerName());
                }
            }
        }
        
        syncDbSync.setCreateTime(DateUtils.getNowDate());
        return syncDbSyncMapper.insertSyncDbSync(syncDbSync);
    }

    /**
     * 修改数据库同步
     * 
     * @param syncDbSync 数据库同步
     * @return 结果
     */
    @Override
    public int updateSyncDbSync(SyncDbSync syncDbSync)
    {
        // 获取数据库名称和服务器名称
        if (syncDbSync.getSourceDbId() != null) {
            SyncDatabase sourceDb = syncDatabaseMapper.selectSyncDatabaseByDbId(syncDbSync.getSourceDbId());
            if (sourceDb != null) {
                syncDbSync.setSourceDbName(sourceDb.getDbName());
                
                // 获取服务器信息
                SyncServer sourceServer = syncServerMapper.selectSyncServerByServerId(sourceDb.getServerId());
                if (sourceServer != null) {
                    // 设置源数据库服务器名称
                    syncDbSync.setSourceServerName(sourceServer.getServerName());
                }
            }
        }
        
        if (syncDbSync.getTargetDbId() != null) {
            SyncDatabase targetDb = syncDatabaseMapper.selectSyncDatabaseByDbId(syncDbSync.getTargetDbId());
            if (targetDb != null) {
                syncDbSync.setTargetDbName(targetDb.getDbName());
                
                // 获取服务器信息
                SyncServer targetServer = syncServerMapper.selectSyncServerByServerId(targetDb.getServerId());
                if (targetServer != null) {
                    // 设置目标数据库服务器名称
                    syncDbSync.setTargetServerName(targetServer.getServerName());
                }
            }
        }
        
        syncDbSync.setUpdateTime(DateUtils.getNowDate());
        return syncDbSyncMapper.updateSyncDbSync(syncDbSync);
    }

    /**
     * 批量删除数据库同步
     * 
     * @param syncIds 需要删除的数据库同步主键
     * @return 结果
     */
    @Override
    public int deleteSyncDbSyncBySyncIds(Long[] syncIds)
    {
        return syncDbSyncMapper.deleteSyncDbSyncBySyncIds(syncIds);
    }

    /**
     * 删除数据库同步信息
     * 
     * @param syncId 数据库同步主键
     * @return 结果
     */
    @Override
    public int deleteSyncDbSyncBySyncId(Long syncId)
    {
        return syncDbSyncMapper.deleteSyncDbSyncBySyncId(syncId);
    }
    
    /**
     * 执行数据库同步
     *
     * @param syncId 数据库同步主键
     * @return 结果
     */
    @Override
    public boolean executeSyncTask(Long syncId)
    {
        // 获取同步任务信息
        SyncDbSync syncTask = syncDbSyncMapper.selectSyncDbSyncBySyncId(syncId);
        if (syncTask == null || !"0".equals(syncTask.getStatus())) {
            System.out.println("同步任务不存在或状态不正常，syncId=" + syncId + ", status=" + (syncTask != null ? syncTask.getStatus() : "null"));
            return false;
        }

        // 检查是否是备份任务
        if (isBackupTask(syncTask)) {
            return executeBackupTask(syncTask);
        }
        
        // 获取源数据库和目标数据库
        SyncDatabase sourceDb = syncDatabaseMapper.selectSyncDatabaseByDbId(syncTask.getSourceDbId());
        SyncDatabase targetDb = syncDatabaseMapper.selectSyncDatabaseByDbId(syncTask.getTargetDbId());
        if (sourceDb == null || targetDb == null) {
            System.out.println("源数据库或目标数据库不存在，sourceDbId=" + syncTask.getSourceDbId() + ", targetDbId=" + syncTask.getTargetDbId());
            return false;
        }
        
        System.out.println("源数据库: " + sourceDb.getDbName() + ", 类型: " + sourceDb.getDbType());
        System.out.println("目标数据库: " + targetDb.getDbName() + ", 类型: " + targetDb.getDbType());
        
        // 获取源服务器和目标服务器
        SyncServer sourceServer = syncServerMapper.selectSyncServerByServerId(sourceDb.getServerId());
        SyncServer targetServer = syncServerMapper.selectSyncServerByServerId(targetDb.getServerId());
        if (sourceServer == null || targetServer == null) {
            System.out.println("源服务器或目标服务器不存在，sourceServerId=" + sourceDb.getServerId() + ", targetServerId=" + targetDb.getServerId());
            return false;
        }
        
        System.out.println("源服务器: " + sourceServer.getServerName() + ", IP: " + sourceServer.getIpAddress());
        System.out.println("目标服务器: " + targetServer.getServerName() + ", IP: " + targetServer.getIpAddress());
        
        Connection sourceConn = null;
        Connection targetConn = null;
        
        try {
            // 建立源数据库和目标数据库的连接
            System.out.println("正在连接源数据库...");
            sourceConn = getConnection(sourceDb, sourceServer);
            System.out.println("正在连接目标数据库...");
            targetConn = getConnection(targetDb, targetServer);
            
            if (sourceConn == null || targetConn == null) {
                String errorMsg = "无法连接到数据库，sourceConn=" + (sourceConn != null ? "成功" : "失败") 
                    + ", targetConn=" + (targetConn != null ? "成功" : "失败");
                System.out.println(errorMsg);
                throw new Exception(errorMsg);
            }
            
            // 获取要同步的表列表
            List<String> tableList;
            if (StringUtils.isEmpty(syncTask.getSyncTables())) {
                // 如果没有指定表，则同步所有表
                tableList = getAllTables(sourceConn, sourceDb.getDbName());
            } else {
                // 如果指定了表，则同步指定的表
                tableList = Arrays.asList(syncTask.getSyncTables().split(","));
            }
            
            if (tableList.isEmpty()) {
                throw new Exception("没有可同步的表");
            }
            
            // 根据同步类型执行全量或增量同步
            if ("1".equals(syncTask.getSyncMode())) {
                // 全量同步
                for (String tableName : tableList) {
                    syncTable(sourceConn, targetConn, tableName, sourceDb, targetDb, false);
                }
            } else if ("2".equals(syncTask.getSyncMode())) {
                // 增量同步
                for (String tableName : tableList) {
                    syncTable(sourceConn, targetConn, tableName, sourceDb, targetDb, true);
                }
            }
            
            // 更新最后执行时间和下次执行时间
            syncTask.setLastExecTime(DateUtils.getTime());
            
            // 计算下次执行时间
            if (!"0".equals(syncTask.getExecCycle()) && StringUtils.isNotEmpty(syncTask.getExecTime())) {
                syncTask.setNextExecTime(calculateNextExecTime(syncTask.getExecCycle(), syncTask.getExecTime()));
            }
            
            syncDbSyncMapper.updateSyncDbSync(syncTask);
            
            // 记录同步日志
            saveSyncLog(syncId, true, "同步成功，同步了 " + tableList.size() + " 个表");
            
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            // 记录同步日志
            saveSyncLog(syncId, false, "同步失败：" + e.getMessage());
            return false;
        } finally {
            closeConnection(sourceConn, null, null);
            closeConnection(targetConn, null, null);
        }
    }

    /**
     * 获取数据库所有表
     */
    private List<String> getAllTables(Connection conn, String dbName) throws SQLException {
        List<String> tables = new ArrayList<>();
        DatabaseMetaData metaData = conn.getMetaData();
        ResultSet rs = metaData.getTables(dbName, null, "%", new String[]{"TABLE"});
        
        while (rs.next()) {
            tables.add(rs.getString("TABLE_NAME"));
        }
        
        rs.close();
        return tables;
    }

    /**
     * 同步表
     */
    private void syncTable(Connection sourceConn, Connection targetConn, String tableName, 
                          SyncDatabase sourceDb, SyncDatabase targetDb, boolean isIncremental) throws Exception {
        // 1. 获取表结构
        Map<String, ColumnInfo> columns = getTableColumns(sourceConn, sourceDb.getDbName(), tableName);
        if (columns.isEmpty()) {
            throw new Exception("表 " + tableName + " 结构获取失败");
        }
        
        // 2. 检查目标表是否存在，不存在则创建
        boolean tableExists = checkTableExists(targetConn, targetDb.getDbName(), tableName);
        if (!tableExists) {
            createTable(targetConn, targetDb.getDbName(), tableName, columns);
        } else {
            // 表存在，检查并更新表结构
            updateTableStructure(targetConn, targetDb.getDbName(), tableName, columns);
        }
        
        // 3. 同步数据
        if (isIncremental) {
            // 增量同步
            syncDataIncremental(sourceConn, targetConn, tableName, columns);
        } else {
            // 全量同步
            syncDataFull(sourceConn, targetConn, tableName, columns);
        }
    }

    /**
     * 获取表字段信息
     */
    private Map<String, ColumnInfo> getTableColumns(Connection conn, String dbName, String tableName) throws SQLException {
        Map<String, ColumnInfo> columns = new LinkedHashMap<>();
        DatabaseMetaData metaData = conn.getMetaData();

        // 获取主键信息
        Set<String> primaryKeys = new HashSet<>();
        ResultSet pkRs = metaData.getPrimaryKeys(dbName, null, tableName);
        while (pkRs.next()) {
            primaryKeys.add(pkRs.getString("COLUMN_NAME"));
        }
        pkRs.close();

        // 先尝试通过SHOW CREATE TABLE获取完整的字段定义
        Map<String, String> fullColumnDefinitions = getFullColumnDefinitions(conn, tableName);

        // 获取字段信息
        ResultSet rs = metaData.getColumns(dbName, null, tableName, "%");
        while (rs.next()) {
            String columnName = rs.getString("COLUMN_NAME");
            ColumnInfo column = new ColumnInfo();
            column.setName(columnName);

            // 获取并可能修正列类型
            String typeName = rs.getString("TYPE_NAME");

            // 如果有完整的字段定义，使用它来获取准确的类型信息
            if (fullColumnDefinitions.containsKey(columnName)) {
                String fullDefinition = fullColumnDefinitions.get(columnName);
                typeName = extractTypeFromFullDefinition(fullDefinition);
            }

            // 对于DATETIME和TIMESTAMP类型，不保留精度信息
            if (typeName.toUpperCase().contains("DATETIME") || typeName.toUpperCase().contains("TIMESTAMP")) {
                // 去除可能的精度部分，如DATETIME(6)只保留DATETIME
                typeName = typeName.replaceAll("\\(\\d+\\)", "");
            }
            column.setType(typeName);

            column.setSize(rs.getInt("COLUMN_SIZE"));
            column.setDecimalDigits(rs.getInt("DECIMAL_DIGITS"));
            column.setNullable(rs.getInt("NULLABLE") == DatabaseMetaData.columnNullable);
            column.setDefaultValue(rs.getString("COLUMN_DEF"));
            column.setPrimaryKey(primaryKeys.contains(columnName));
            column.setAutoIncrement(rs.getString("IS_AUTOINCREMENT").equals("YES"));

            columns.put(columnName, column);
        }
        rs.close();

        return columns;
    }

    /**
     * 通过SHOW CREATE TABLE获取完整的字段定义
     */
    private Map<String, String> getFullColumnDefinitions(Connection conn, String tableName) {
        Map<String, String> columnDefinitions = new HashMap<>();
        Statement stmt = null;
        ResultSet rs = null;

        try {
            stmt = conn.createStatement();
            // 获取数据库类型
            String dbType = getDatabaseType(conn);
            String sql;
            if ("mysql".equalsIgnoreCase(dbType)) {
                sql = "SHOW CREATE TABLE `" + tableName + "`";
            } else {
                // 对于非MySQL数据库，跳过此方法，因为它们不支持SHOW CREATE TABLE
                return columnDefinitions;
            }
            rs = stmt.executeQuery(sql);

            if (rs.next()) {
                String createTableSql = rs.getString(2);
                System.out.println("同步表的ddl:" + createTableSql);

                // 解析CREATE TABLE语句中的字段定义
                String[] lines = createTableSql.split("\n");
                for (String line : lines) {
                    line = line.trim();
                    if (line.startsWith("`") && line.contains(" ")) {
                        // 提取字段名
                        int firstBacktick = line.indexOf("`");
                        int secondBacktick = line.indexOf("`", firstBacktick + 1);
                        if (firstBacktick >= 0 && secondBacktick > firstBacktick) {
                            String columnName = line.substring(firstBacktick + 1, secondBacktick);
                            // 提取字段定义（去掉字段名和反引号）
                            String columnDef = line.substring(secondBacktick + 1).trim();
                            // 去掉末尾的逗号
                            if (columnDef.endsWith(",")) {
                                columnDef = columnDef.substring(0, columnDef.length() - 1);
                            }
                            columnDefinitions.put(columnName, columnDef);
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("获取完整字段定义失败: " + e.getMessage());
            // 如果获取失败，返回空Map，使用原有逻辑
        } finally {
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
            } catch (SQLException e) {
                // 忽略关闭异常
            }
        }

        return columnDefinitions;
    }

    /**
     * 从完整的字段定义中提取类型信息
     */
    private String extractTypeFromFullDefinition(String fullDefinition) {
        // 示例输入: "int(1) unsigned zerofill DEFAULT '0' COMMENT '字典类型0为string,1为number'"
        // 期望输出: "int(1) unsigned zerofill"

        String typePart = fullDefinition;

        // 找到第一个非类型关键字的位置
        String[] nonTypeKeywords = {"DEFAULT", "COMMENT", "NOT", "NULL", "AUTO_INCREMENT", "PRIMARY", "KEY"};
        int minIndex = typePart.length();

        for (String keyword : nonTypeKeywords) {
            int index = typePart.toUpperCase().indexOf(" " + keyword);
            if (index > 0 && index < minIndex) {
                minIndex = index;
            }
        }

        if (minIndex < typePart.length()) {
            typePart = typePart.substring(0, minIndex).trim();
        }

        // 转换不兼容的排序规则
        typePart = convertIncompatibleCollation(typePart);

        return typePart;
    }

    /**
     * 检查是否是完整的类型定义（包含长度、UNSIGNED、ZEROFILL等属性）
     */
    private boolean isCompleteTypeDefinition(String columnType) {
        String upperType = columnType.toUpperCase();
        return upperType.contains("UNSIGNED") ||
               upperType.contains("ZEROFILL") ||
               upperType.contains("BINARY") ||
               upperType.contains("CHARACTER SET") ||
               upperType.contains("COLLATE") ||
               hasLengthInDefinition(columnType);
    }

    /**
     * 检查类型定义是否已经包含长度信息
     */
    private boolean hasLengthInDefinition(String columnType) {
        // 检查是否包含括号，表示已经有长度定义
        return columnType.contains("(") && columnType.contains(")");
    }

    /**
     * 检查是否是不需要长度定义的类型
     */
    private boolean isTypeWithoutLength(String columnType) {
        String upperType = columnType.toUpperCase();

        // BLOB类型
        if (upperType.equals("TINYBLOB") || upperType.equals("BLOB") ||
            upperType.equals("MEDIUMBLOB") || upperType.equals("LONGBLOB")) {
            return true;
        }

        // TEXT类型
        if (upperType.equals("TINYTEXT") || upperType.equals("TEXT") ||
            upperType.equals("MEDIUMTEXT") || upperType.equals("LONGTEXT")) {
            return true;
        }

        // 日期时间类型
        if (upperType.equals("DATE") || upperType.equals("TIME") ||
            upperType.equals("DATETIME") || upperType.equals("TIMESTAMP") ||
            upperType.equals("YEAR")) {
            return true;
        }

        // JSON类型
        if (upperType.equals("JSON")) {
            return true;
        }

        // 几何类型
        if (upperType.equals("GEOMETRY") || upperType.equals("POINT") ||
            upperType.equals("LINESTRING") || upperType.equals("POLYGON") ||
            upperType.equals("MULTIPOINT") || upperType.equals("MULTILINESTRING") ||
            upperType.equals("MULTIPOLYGON") || upperType.equals("GEOMETRYCOLLECTION")) {
            return true;
        }

        return false;
    }

    /**
     * 转换不兼容的排序规则为兼容版本
     */
    private String convertIncompatibleCollation(String typeDefinition) {
        if (typeDefinition == null) {
            return typeDefinition;
        }

        // MySQL 8.0 排序规则兼容性转换
        String result = typeDefinition;

        // utf8mb4_0900_ai_ci -> utf8mb4_general_ci (最常用的兼容替代)
        result = result.replace("utf8mb4_0900_ai_ci", "utf8mb4_general_ci");

        // utf8mb4_0900_as_ci -> utf8mb4_unicode_ci (区分重音的版本)
        result = result.replace("utf8mb4_0900_as_ci", "utf8mb4_unicode_ci");

        // utf8mb4_0900_as_cs -> utf8mb4_bin (区分大小写的版本)
        result = result.replace("utf8mb4_0900_as_cs", "utf8mb4_bin");

        // utf8_0900_ai_ci -> utf8_general_ci
        result = result.replace("utf8_0900_ai_ci", "utf8_general_ci");

        // utf8_0900_as_ci -> utf8_unicode_ci
        result = result.replace("utf8_0900_as_ci", "utf8_unicode_ci");

        // utf8_0900_as_cs -> utf8_bin
        result = result.replace("utf8_0900_as_cs", "utf8_bin");

        return result;
    }

    /**
     * 检查表是否存在
     */
    private boolean checkTableExists(Connection conn, String dbName, String tableName) throws SQLException {
        DatabaseMetaData metaData = conn.getMetaData();
        ResultSet rs = metaData.getTables(dbName, null, tableName, new String[]{"TABLE"});
        boolean exists = rs.next();
        rs.close();
        return exists;
    }

    /**
     * 创建表
     */
    private void createTable(Connection conn, String dbName, String tableName, Map<String, ColumnInfo> columns) throws SQLException {
        // 获取数据库类型以确定正确的SQL语法
        String dbType = getDatabaseType(conn);

        // 临时禁用MySQL的严格模式，允许使用零日期值（仅对MySQL有效）
        if ("mysql".equalsIgnoreCase(dbType)) {
            Statement modeStmt = null;
            try {
                modeStmt = conn.createStatement();
                modeStmt.execute("SET SESSION sql_mode = ''");
            } catch (Exception e) {
                // 忽略设置SQL_MODE的错误
                System.out.println("设置SQL_MODE失败: " + e.getMessage());
            } finally {
                if (modeStmt != null) {
                    modeStmt.close();
                }
            }
        }

        StringBuilder sql = new StringBuilder();
        sql.append("CREATE TABLE ").append(getQuotedIdentifier(tableName, dbType)).append(" (");
        
        List<String> primaryKeys = new ArrayList<>();
        
        int i = 0;
        for (Map.Entry<String, ColumnInfo> entry : columns.entrySet()) {
            ColumnInfo column = entry.getValue();

            if (i > 0) {
                sql.append(", ");
            }

            sql.append(getQuotedIdentifier(column.getName(), dbType)).append(" ");
            String columnType = column.getType();

            // 根据目标数据库类型转换数据类型
            String originalType = columnType;
            columnType = convertDataType(columnType, dbType);
            System.out.println("列 " + column.getName() + ": " + originalType + " -> " + columnType);
            if (!originalType.equals(columnType)) {
                System.out.println("*** 数据类型已转换: " + originalType + " -> " + columnType);
            }

            // 检查是否已经是完整的类型定义（包含UNSIGNED、ZEROFILL等）
            boolean isCompleteType = isCompleteTypeDefinition(columnType);

            if (isCompleteType) {
                // 如果是完整定义，直接使用，但需要处理DATETIME和TIMESTAMP的精度
                if (columnType.toUpperCase().contains("DATETIME") || columnType.toUpperCase().contains("TIMESTAMP")) {
                    // 移除可能的精度部分，如DATETIME(6)只保留DATETIME
                    columnType = columnType.replaceAll("\\(\\d+\\)", "");
                }
                // 转换不兼容的排序规则（仅对MySQL有效）
                if ("mysql".equalsIgnoreCase(dbType)) {
                    columnType = convertIncompatibleCollation(columnType);
                }
                sql.append(columnType);

                // 对于完整定义，检查是否已经包含NOT NULL，如果没有且字段不允许为空，则添加
                if (!column.isNullable() && !columnType.toUpperCase().contains("NOT NULL")) {
                    sql.append(" NOT NULL");
                }
            } else {
                // 如果不是完整定义，使用原有逻辑
                // 处理列类型，确保DATETIME和TIMESTAMP类型不带精度
                if (columnType.toUpperCase().contains("DATETIME") || columnType.toUpperCase().contains("TIMESTAMP")) {
                    // 移除可能的精度部分，如DATETIME(6)只保留DATETIME
                    columnType = columnType.replaceAll("\\(\\d+\\)", "");
                }

                sql.append(columnType);

                // 检查是否需要添加长度定义
                if (!isTypeWithoutLength(columnType)) {
                    // 对于需要长度的类型，添加长度信息
                    if (column.getSize() > 0) {
                        // 达梦数据库的整数类型不支持长度定义
                        if ("dameng".equalsIgnoreCase(dbType) && isIntegerType(columnType)) {
                            // 达梦的整数类型不添加长度
                        } else {
                            if (column.getDecimalDigits() > 0) {
                                sql.append("(").append(column.getSize()).append(",").append(column.getDecimalDigits()).append(")");
                            } else {
                                sql.append("(").append(column.getSize()).append(")");
                            }
                        }
                    }
                }

                // 对于非完整定义，添加NOT NULL
                if (!column.isNullable()) {
                    sql.append(" NOT NULL");
                }
            }
            
            // 处理默认值（只有在完整定义中不包含DEFAULT时才添加）
            String columnName = column.getName().toLowerCase();
            String upperColumnType = columnType.toUpperCase();
            boolean hasDefaultInDefinition = isCompleteType && upperColumnType.contains("DEFAULT");

            if (!hasDefaultInDefinition) {
                // 特殊处理created_at字段和时间戳字段
                if (columnName.equals("created_at") || columnName.equals("updated_at") ||
                    columnName.equals("create_time") || columnName.equals("update_time")) {

                    if (upperColumnType.contains("TIMESTAMP") || upperColumnType.contains("DATETIME")) {
                        // 对于timestamp和datetime类型使用固定且有效的默认值
                        if (column.isNullable()) {
                            sql.append(" DEFAULT NULL");
                        } else {
                            sql.append(" DEFAULT CURRENT_TIMESTAMP");
                        }
                    }
                } else if (column.getDefaultValue() != null) {
                    String defaultValue = column.getDefaultValue();

                    // 特殊处理日期时间类型的默认值
                    if ((upperColumnType.contains("TIMESTAMP") || upperColumnType.contains("DATETIME") || upperColumnType.contains("DATE"))) {
                        if (defaultValue.toUpperCase().contains("CURRENT_TIMESTAMP") || defaultValue.toUpperCase().contains("NOW()")) {
                            sql.append(" DEFAULT CURRENT_TIMESTAMP");
                        } else if (defaultValue.equals("0000-00-00 00:00:00") || defaultValue.equals("0000-00-00")) {
                            if (column.isNullable()) {
                                sql.append(" DEFAULT NULL");
                            } else {
                                sql.append(" DEFAULT CURRENT_TIMESTAMP");
                            }
                        } else if (defaultValue.startsWith("'") && defaultValue.endsWith("'")) {
                            // 已带引号的日期值
                            sql.append(" DEFAULT ").append(defaultValue);
                        } else {
                            // 针对其他日期值，默认加上引号
                            sql.append(" DEFAULT '").append(defaultValue).append("'");
                        }
                    } else {
                        // 非日期类型的处理
                        if (upperColumnType.contains("CHAR") || upperColumnType.contains("TEXT")) {
                            if (defaultValue.startsWith("'") && defaultValue.endsWith("'")) {
                                sql.append(" DEFAULT ").append(defaultValue);
                            } else {
                                sql.append(" DEFAULT '").append(defaultValue).append("'");
                            }
                        } else {
                            sql.append(" DEFAULT ").append(defaultValue);
                        }
                    }
                }
            }
            
            if (column.isAutoIncrement()) {
                sql.append(" AUTO_INCREMENT");
            }
            
            if (column.isPrimaryKey()) {
                primaryKeys.add(column.getName());
            }
            
            i++;
        }
        
        // 添加主键
        if (!primaryKeys.isEmpty()) {
            sql.append(", PRIMARY KEY (");
            for (int j = 0; j < primaryKeys.size(); j++) {
                if (j > 0) {
                    sql.append(", ");
                }
                sql.append(getQuotedIdentifier(primaryKeys.get(j), dbType));
            }
            sql.append(")");
        }

        // 根据数据库类型添加不同的表选项
        if ("mysql".equalsIgnoreCase(dbType)) {
            sql.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
        } else {
            sql.append(")");
        }
        
        Statement stmt = null;
        try {
            stmt = conn.createStatement();
            System.out.println("创建表SQL: " + sql.toString());
            System.out.println("目标数据库类型: " + dbType);
            stmt.execute(sql.toString());
        } finally {
            if (stmt != null) {
                stmt.close();
            }
        }
    }

    /**
     * 更新表结构
     */
    private void updateTableStructure(Connection conn, String dbName, String tableName, Map<String, ColumnInfo> sourceColumns) throws SQLException {
        // 获取目标表的列
        Map<String, ColumnInfo> targetColumns = getTableColumns(conn, dbName, tableName);
        
        // 查找需要添加的列
        List<ColumnInfo> columnsToAdd = new ArrayList<>();
        for (Map.Entry<String, ColumnInfo> entry : sourceColumns.entrySet()) {
            String columnName = entry.getKey();
            ColumnInfo sourceColumn = entry.getValue();
            
            if (!targetColumns.containsKey(columnName)) {
                columnsToAdd.add(sourceColumn);
            }
        }
        
        // 添加新列
        if (!columnsToAdd.isEmpty()) {
            // 获取数据库类型
            String dbType = getDatabaseType(conn);

            for (ColumnInfo column : columnsToAdd) {
                StringBuilder sql = new StringBuilder();
                sql.append("ALTER TABLE ").append(getQuotedIdentifier(tableName, dbType));
                sql.append(" ADD COLUMN ").append(getQuotedIdentifier(column.getName(), dbType)).append(" ");
                String columnType = column.getType();
                // 根据目标数据库类型转换数据类型
                columnType = convertDataType(columnType, dbType);
                // 转换不兼容的排序规则（仅对MySQL有效）
                if ("mysql".equalsIgnoreCase(dbType)) {
                    columnType = convertIncompatibleCollation(columnType);
                }
                sql.append(columnType);

                // 检查是否需要添加长度定义
                if (!isTypeWithoutLength(columnType)) {
                    // 对于需要长度的类型，添加长度信息
                    if (column.getSize() > 0) {
                        // 达梦数据库的整数类型不支持长度定义
                        if ("dameng".equalsIgnoreCase(dbType) && isIntegerType(columnType)) {
                            // 达梦的整数类型不添加长度
                        } else {
                            if (column.getDecimalDigits() > 0) {
                                sql.append("(").append(column.getSize()).append(",").append(column.getDecimalDigits()).append(")");
                            } else {
                                sql.append("(").append(column.getSize()).append(")");
                            }
                        }
                    }
                }
                
                if (!column.isNullable()) {
                    sql.append(" NOT NULL");
                }
                
                if (column.getDefaultValue() != null) {
                    String defaultValue = column.getDefaultValue();
                    
                    // 特殊处理日期时间类型的默认值
                    String upperColumnType = columnType.toUpperCase();
                    if ((upperColumnType.contains("TIMESTAMP") || upperColumnType.contains("DATETIME") || upperColumnType.contains("DATE"))
                            && (defaultValue.toUpperCase().contains("CURRENT_TIMESTAMP")
                                || defaultValue.toUpperCase().contains("NOW()")
                                || defaultValue.equals("0000-00-00 00:00:00")
                                || defaultValue.equals("0000-00-00"))) {
                        
                        // 对于CURRENT_TIMESTAMP，直接使用不带引号
                        if (defaultValue.toUpperCase().contains("CURRENT_TIMESTAMP") || defaultValue.toUpperCase().contains("NOW()")) {
                            sql.append(" DEFAULT CURRENT_TIMESTAMP");
                        } 
                        // 对于0000-00-00 00:00:00这种值，MySQL严格模式下不允许，改用NULL
                        else if (defaultValue.equals("0000-00-00 00:00:00") || defaultValue.equals("0000-00-00")) {
                            if (column.isNullable()) {
                                sql.append(" DEFAULT NULL");
                            } else {
                                // 如果不允许为NULL，则使用一个有效的日期
                                sql.append(" DEFAULT '2000-01-01 00:00:00'");
                            }
                        }
                    } else {
                        // 如果是字符串类型需要加引号，其他类型直接使用
                        if (upperColumnType.contains("CHAR") || upperColumnType.contains("TEXT") || upperColumnType.contains("DATE")
                                || upperColumnType.contains("TIME") || upperColumnType.contains("YEAR")) {
                            // 已经有引号的不要重复添加
                            if (defaultValue.startsWith("'") && defaultValue.endsWith("'")) {
                                sql.append(" DEFAULT ").append(defaultValue);
                            } else {
                                sql.append(" DEFAULT '").append(defaultValue).append("'");
                            }
                        } else {
                            sql.append(" DEFAULT ").append(defaultValue);
                        }
                    }
                }
                
                Statement stmt = conn.createStatement();
                stmt.execute(sql.toString());
                stmt.close();
            }
        }
    }

    /**
     * 全量同步数据
     */
    private void syncDataFull(Connection sourceConn, Connection targetConn, String tableName, Map<String, ColumnInfo> columns) throws SQLException {
        // 1. 清空目标表数据
        Statement truncateStmt = targetConn.createStatement();
        truncateStmt.execute("TRUNCATE TABLE " + tableName);
        truncateStmt.close();
        
        // 2. 获取源表数据
        Statement sourceStmt = sourceConn.createStatement();
        ResultSet rs = sourceStmt.executeQuery("SELECT * FROM " + tableName);
        
        // 3. 插入数据到目标表
        insertDataBatch(targetConn, tableName, columns, rs);
        
        sourceStmt.close();
        rs.close();
    }

    /**
     * 增量同步数据
     */
    private void syncDataIncremental(Connection sourceConn, Connection targetConn, String tableName, Map<String, ColumnInfo> columns) throws SQLException {
        // 获取主键列
        List<String> primaryKeys = getPrimaryKeys(columns);
        if (primaryKeys.isEmpty()) {
            // 如果没有主键，则进行全量同步
            syncDataFull(sourceConn, targetConn, tableName, columns);
            return;
        }
        
        // 1. 获取源表数据
        Statement sourceStmt = sourceConn.createStatement();
        ResultSet rs = sourceStmt.executeQuery("SELECT * FROM " + tableName);
        
        // 2. 根据主键更新或插入数据
        while (rs.next()) {
            StringBuilder whereClause = new StringBuilder();
            for (int i = 0; i < primaryKeys.size(); i++) {
                String pkColumn = primaryKeys.get(i);
                if (i > 0) {
                    whereClause.append(" AND ");
                }
                Object pkValue = rs.getObject(pkColumn);
                if (pkValue == null) {
                    whereClause.append(pkColumn).append(" IS NULL");
                } else {
                    whereClause.append(pkColumn).append(" = ?");
                }
            }
            
            // 检查记录是否存在
            StringBuilder checkSql = new StringBuilder();
            checkSql.append("SELECT COUNT(*) FROM ").append(tableName);
            checkSql.append(" WHERE ").append(whereClause);
            
            PreparedStatement checkStmt = targetConn.prepareStatement(checkSql.toString());
            int paramIndex = 1;
            for (String pkColumn : primaryKeys) {
                Object pkValue = rs.getObject(pkColumn);
                if (pkValue != null) {
                    checkStmt.setObject(paramIndex++, pkValue);
                }
            }
            
            ResultSet checkRs = checkStmt.executeQuery();
            checkRs.next();
            int count = checkRs.getInt(1);
            checkRs.close();
            checkStmt.close();
            
            if (count > 0) {
                // 记录存在，执行更新
                updateRecord(targetConn, tableName, columns, primaryKeys, rs);
            } else {
                // 记录不存在，执行插入
                insertRecord(targetConn, tableName, columns, rs);
            }
        }
        
        sourceStmt.close();
        rs.close();
    }

    /**
     * 获取主键列表
     */
    private List<String> getPrimaryKeys(Map<String, ColumnInfo> columns) {
        List<String> primaryKeys = new ArrayList<>();
        for (Map.Entry<String, ColumnInfo> entry : columns.entrySet()) {
            if (entry.getValue().isPrimaryKey()) {
                primaryKeys.add(entry.getKey());
            }
        }
        return primaryKeys;
    }

    /**
     * 批量插入数据
     */
    private void insertDataBatch(Connection conn, String tableName, Map<String, ColumnInfo> columns, ResultSet sourceRs) throws SQLException {
        // 准备插入语句
        StringBuilder sql = new StringBuilder();
        // 获取数据库类型
        String dbType = getDatabaseType(conn);
        sql.append("INSERT INTO ").append(getQuotedIdentifier(tableName, dbType)).append(" (");

        int i = 0;
        for (String columnName : columns.keySet()) {
            if (i > 0) {
                sql.append(", ");
            }
            sql.append(getQuotedIdentifier(columnName, dbType));
            i++;
        }
        
        sql.append(") VALUES (");
        
        for (i = 0; i < columns.size(); i++) {
            if (i > 0) {
                sql.append(", ");
            }
            sql.append("?");
        }
        
        sql.append(")");
        
        PreparedStatement pstmt = conn.prepareStatement(sql.toString());
        int batchSize = 0;
        int maxBatchSize = 1000; // 每批处理的最大记录数
        
        conn.setAutoCommit(false);
        
        while (sourceRs.next()) {
            int paramIndex = 1;
            for (String columnName : columns.keySet()) {
                Object value = sourceRs.getObject(columnName);
                pstmt.setObject(paramIndex++, value);
            }
            
            pstmt.addBatch();
            batchSize++;
            
            if (batchSize >= maxBatchSize) {
                pstmt.executeBatch();
                conn.commit();
                batchSize = 0;
            }
        }
        
        if (batchSize > 0) {
            pstmt.executeBatch();
            conn.commit();
        }
        
        conn.setAutoCommit(true);
        pstmt.close();
    }

    /**
     * 更新记录
     */
    private void updateRecord(Connection conn, String tableName, Map<String, ColumnInfo> columns, List<String> primaryKeys, ResultSet sourceRs) throws SQLException {
        // 准备更新语句
        StringBuilder sql = new StringBuilder();
        sql.append("UPDATE ").append(tableName).append(" SET ");
        
        List<String> updateColumns = new ArrayList<>();
        for (String columnName : columns.keySet()) {
            if (!primaryKeys.contains(columnName)) {
                updateColumns.add(columnName);
            }
        }
        
        for (int i = 0; i < updateColumns.size(); i++) {
            if (i > 0) {
                sql.append(", ");
            }
            sql.append(updateColumns.get(i)).append(" = ?");
        }
        
        sql.append(" WHERE ");
        
        for (int i = 0; i < primaryKeys.size(); i++) {
            if (i > 0) {
                sql.append(" AND ");
            }
            sql.append(primaryKeys.get(i)).append(" = ?");
        }
        
        PreparedStatement pstmt = conn.prepareStatement(sql.toString());
        
        // 设置更新字段的值
        int paramIndex = 1;
        for (String columnName : updateColumns) {
            Object value = sourceRs.getObject(columnName);
            pstmt.setObject(paramIndex++, value);
        }
        
        // 设置主键字段的值
        for (String pkColumn : primaryKeys) {
            Object pkValue = sourceRs.getObject(pkColumn);
            pstmt.setObject(paramIndex++, pkValue);
        }
        
        pstmt.executeUpdate();
        pstmt.close();
    }

    /**
     * 插入记录
     */
    private void insertRecord(Connection conn, String tableName, Map<String, ColumnInfo> columns, ResultSet sourceRs) throws SQLException {
        // 准备插入语句
        StringBuilder sql = new StringBuilder();
        // 获取数据库类型
        String dbType = getDatabaseType(conn);
        sql.append("INSERT INTO ").append(getQuotedIdentifier(tableName, dbType)).append(" (");

        int i = 0;
        for (String columnName : columns.keySet()) {
            if (i > 0) {
                sql.append(", ");
            }
            sql.append(getQuotedIdentifier(columnName, dbType));
            i++;
        }
        
        sql.append(") VALUES (");
        
        for (i = 0; i < columns.size(); i++) {
            if (i > 0) {
                sql.append(", ");
            }
            sql.append("?");
        }
        
        sql.append(")");
        
        PreparedStatement pstmt = conn.prepareStatement(sql.toString());
        
        int paramIndex = 1;
        for (String columnName : columns.keySet()) {
            Object value = sourceRs.getObject(columnName);
            pstmt.setObject(paramIndex++, value);
        }
        
        pstmt.executeUpdate();
        pstmt.close();
    }

    /**
     * 计算下次执行时间
     */
    private String calculateNextExecTime(String execCycle, String execTime) {
        LocalDateTime now = LocalDateTime.now();
        LocalTime time = LocalTime.parse(execTime);
        
        LocalDateTime nextExec = now.withHour(time.getHour()).withMinute(time.getMinute()).withSecond(0);
        
        switch (execCycle) {
            case "1": // 每天
                if (now.isAfter(nextExec)) {
                    nextExec = nextExec.plusDays(1);
                }
                break;
            case "2": // 每周
                nextExec = nextExec.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
                break;
            case "3": // 每月
                nextExec = nextExec.with(TemporalAdjusters.firstDayOfNextMonth());
                break;
        }
        
        return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(nextExec);
    }

    /**
     * 记录同步日志
     */
    private void saveSyncLog(Long syncId, boolean success, String message) {
        SyncLog log = new SyncLog();
        log.setSyncId(syncId);
        log.setExecTime(DateUtils.getNowDate());
        log.setSuccess(success ? "0" : "1"); // 0-成功，1-失败
        log.setMessage(message);
        
        syncLogMapper.insertSyncLog(log);
    }

    /**
     * 获取数据库连接
     */
    private Connection getConnection(SyncDatabase database, SyncServer server) {
        try {
            // 构建JDBC URL
            StringBuilder urlBuilder = new StringBuilder("jdbc:");
            String dbType = database.getDbType();
            String driverClass = null;
            
            // 根据数据库类型构建JDBC URL
            if ("1".equals(dbType) || "MySQL".equalsIgnoreCase(dbType)) {
                urlBuilder.append("mysql://").append(server.getIpAddress())
                        .append(":").append(database.getDbPort())
                        .append("/").append(database.getDbName());
                urlBuilder.append("?useUnicode=true&characterEncoding=utf8&useSSL=false");
                driverClass = "com.mysql.cj.jdbc.Driver";
            } else if ("2".equals(dbType) || "Oracle".equalsIgnoreCase(dbType)) {
                urlBuilder.append("oracle:thin:@").append(server.getIpAddress())
                        .append(":").append(database.getDbPort())
                        .append(":").append(database.getDbName());
                driverClass = "oracle.jdbc.driver.OracleDriver";
            } else if ("3".equals(dbType) || "SQLServer".equalsIgnoreCase(dbType)) {
                urlBuilder.append("sqlserver://").append(server.getIpAddress())
                        .append(":").append(database.getDbPort())
                        .append(";databaseName=").append(database.getDbName());
                driverClass = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
            } else if ("4".equals(dbType) || "PostgreSQL".equalsIgnoreCase(dbType)) {
                urlBuilder.append("postgresql://").append(server.getIpAddress())
                        .append(":").append(database.getDbPort())
                        .append("/").append(database.getDbName());
                driverClass = "org.postgresql.Driver";
            } else if ("dameng".equalsIgnoreCase(dbType)) {
                urlBuilder.append("dm://").append(server.getIpAddress())
                        .append(":").append(database.getDbPort())
                        .append("/").append(database.getDbName());
                driverClass = "dm.jdbc.driver.DmDriver";
            } else {
                System.out.println("不支持的数据库类型: " + dbType);
                return null;
            }
            
            // 创建数据库连接
            System.out.println("尝试连接到数据库: " + urlBuilder.toString() + ", 用户名: " + database.getDbUsername());
            Class.forName(driverClass);
            Connection conn = DriverManager.getConnection(urlBuilder.toString(), 
                    database.getDbUsername(), database.getDbPassword());
            System.out.println("数据库连接成功");
            return conn;
        } catch (Exception e) {
            System.out.println("连接数据库失败: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * 关闭数据库连接和相关资源
     */
    private void closeConnection(Connection conn, Statement stmt, ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
            if (stmt != null) {
                stmt.close();
            }
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 数据库字段信息类
     */
    private class ColumnInfo {
        private String name;
        private String type;
        private int size;
        private int decimalDigits;
        private boolean nullable;
        private String defaultValue;
        private boolean primaryKey;
        private boolean autoIncrement;
        
        public String getName() {
            return name;
        }
        
        public void setName(String name) {
            this.name = name;
        }
        
        public String getType() {
            return type;
        }
        
        public void setType(String type) {
            this.type = type;
        }
        
        public int getSize() {
            return size;
        }
        
        public void setSize(int size) {
            this.size = size;
        }
        
        public int getDecimalDigits() {
            return decimalDigits;
        }
        
        public void setDecimalDigits(int decimalDigits) {
            this.decimalDigits = decimalDigits;
        }
        
        public boolean isNullable() {
            return nullable;
        }
        
        public void setNullable(boolean nullable) {
            this.nullable = nullable;
        }
        
        public String getDefaultValue() {
            return defaultValue;
        }
        
        public void setDefaultValue(String defaultValue) {
            this.defaultValue = defaultValue;
        }
        
        public boolean isPrimaryKey() {
            return primaryKey;
        }
        
        public void setPrimaryKey(boolean primaryKey) {
            this.primaryKey = primaryKey;
        }
        
        public boolean isAutoIncrement() {
            return autoIncrement;
        }
        
        public void setAutoIncrement(boolean autoIncrement) {
            this.autoIncrement = autoIncrement;
        }
    }

    /**
     * 判断是否是备份任务
     *
     * @param syncTask 同步任务
     * @return 是否是备份任务
     */
    private boolean isBackupTask(SyncDbSync syncTask) {
        // 通过任务名称判断是否是备份任务
        return syncTask.getSyncName() != null && syncTask.getSyncName().startsWith("备份任务-");
    }

    /**
     * 执行备份任务
     *
     * @param syncTask 同步任务
     * @return 执行结果
     */
    private boolean executeBackupTask(SyncDbSync syncTask) {
        try {
            System.out.println("开始执行备份任务：" + syncTask.getSyncName());

            // 获取数据库信息
            SyncDatabase database = syncDatabaseMapper.selectSyncDatabaseByDbId(syncTask.getSourceDbId());
            if (database == null) {
                System.out.println("备份任务执行失败：数据库不存在，dbId=" + syncTask.getSourceDbId());
                return false;
            }

            // 执行备份
            String backupFilePath = null;
            if (database.getBackupServerId() != null) {
                // 远程备份
                backupFilePath = syncDatabaseService.remoteBackupDatabase(
                    database.getDbId(),
                    database.getBackupServerId(),
                    database.getBackupPath()
                );
            } else {
                // 本地备份
                backupFilePath = syncDatabaseService.backupDatabase(database.getDbId());
            }

            // 更新任务执行时间
            syncTask.setLastExecTime(DateUtils.getTime());

            // 计算下次执行时间
            if (!"0".equals(syncTask.getExecCycle()) && StringUtils.isNotEmpty(syncTask.getExecTime())) {
                syncTask.setNextExecTime(calculateNextExecTime(syncTask.getExecCycle(), syncTask.getExecTime()));
            }

            syncDbSyncMapper.updateSyncDbSync(syncTask);

            if (backupFilePath != null) {
                // 更新数据库的最后备份时间
                database.setLastBackupTime(DateUtils.getNowDate());
                syncDatabaseMapper.updateSyncDatabase(database);

                System.out.println("备份任务执行成功：" + syncTask.getSyncName() + "，备份文件：" + backupFilePath);
                return true;
            } else {
                System.out.println("备份任务执行失败：" + syncTask.getSyncName());
                return false;
            }
        } catch (Exception e) {
            System.out.println("备份任务执行异常：" + syncTask.getSyncName() + "，错误：" + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取数据库类型
     */
    private String getDatabaseType(Connection conn) {
        try {
            String url = conn.getMetaData().getURL();
            if (url.contains("mysql")) {
                return "mysql";
            } else if (url.contains("oracle")) {
                return "oracle";
            } else if (url.contains("sqlserver")) {
                return "sqlserver";
            } else if (url.contains("postgresql")) {
                return "postgresql";
            } else if (url.contains("dm:")) {
                return "dameng";
            } else {
                return "mysql"; // 默认返回mysql
            }
        } catch (Exception e) {
            System.out.println("获取数据库类型失败: " + e.getMessage());
            return "mysql"; // 默认返回mysql
        }
    }

    /**
     * 根据数据库类型获取带引号的标识符
     */
    private String getQuotedIdentifier(String identifier, String dbType) {
        if ("mysql".equalsIgnoreCase(dbType)) {
            return "`" + identifier + "`";
        } else if ("dameng".equalsIgnoreCase(dbType) || "oracle".equalsIgnoreCase(dbType) || "postgresql".equalsIgnoreCase(dbType)) {
            return "\"" + identifier + "\"";
        } else if ("sqlserver".equalsIgnoreCase(dbType)) {
            return "[" + identifier + "]";
        } else {
            return "`" + identifier + "`"; // 默认使用MySQL语法
        }
    }

    /**
     * 根据目标数据库类型转换数据类型
     */
    private String convertDataType(String sourceType, String targetDbType) {
        if (sourceType == null) {
            return sourceType;
        }

        // 如果目标是MySQL，保持原样
        if ("mysql".equalsIgnoreCase(targetDbType)) {
            return sourceType;
        }

        String upperType = sourceType.toUpperCase().trim();

        if ("dameng".equalsIgnoreCase(targetDbType)) {
            // 清理可能的额外信息（如UNSIGNED、ZEROFILL等）
            String cleanType = cleanTypeDefinition(upperType);

            // 处理常见的MySQL特有类型转换为达梦兼容类型
            if (cleanType.startsWith("TEXT")) {
                return "CLOB"; // TEXT转换为CLOB
            } else if (cleanType.startsWith("LONGTEXT")) {
                return "CLOB"; // LONGTEXT转换为CLOB
            } else if (cleanType.startsWith("MEDIUMTEXT")) {
                return "CLOB"; // MEDIUMTEXT转换为CLOB
            } else if (cleanType.startsWith("TINYTEXT")) {
                return "VARCHAR(255)"; // TINYTEXT转换为VARCHAR
            } else if (cleanType.startsWith("INT(") || cleanType.equals("INT")) {
                return "INT"; // 达梦支持INT类型
            } else if (cleanType.startsWith("INTEGER(") || cleanType.equals("INTEGER")) {
                return "INT"; // INTEGER转换为INT
            } else if (cleanType.startsWith("TINYINT(") || cleanType.equals("TINYINT")) {
                return "TINYINT"; // 达梦支持TINYINT
            } else if (cleanType.startsWith("SMALLINT(") || cleanType.equals("SMALLINT")) {
                return "SMALLINT"; // 达梦支持SMALLINT
            } else if (cleanType.startsWith("BIGINT(") || cleanType.equals("BIGINT")) {
                return "BIGINT"; // 达梦支持BIGINT
            } else if (cleanType.startsWith("LONGBLOB")) {
                return "BLOB"; // LONGBLOB转换为BLOB
            } else if (cleanType.startsWith("MEDIUMBLOB")) {
                return "BLOB"; // MEDIUMBLOB转换为BLOB
            } else if (cleanType.startsWith("TINYBLOB")) {
                return "BLOB"; // TINYBLOB转换为BLOB
            } else if (cleanType.contains("UNSIGNED") || cleanType.contains("ZEROFILL")) {
                // 移除MySQL特有的UNSIGNED和ZEROFILL关键字
                return cleanType.replaceAll("\\s+UNSIGNED", "").replaceAll("\\s+ZEROFILL", "").trim();
            } else if (cleanType.startsWith("BIT(")) {
                // BIT类型转换
                return "BIT" + cleanType.substring(3); // 保留长度
            } else if (cleanType.equals("BIT")) {
                return "BIT(1)"; // 默认BIT(1)
            } else if (cleanType.startsWith("ENUM(")) {
                // ENUM类型转换为VARCHAR
                return "VARCHAR(255)";
            } else if (cleanType.startsWith("SET(")) {
                // SET类型转换为VARCHAR
                return "VARCHAR(255)";
            } else if (cleanType.startsWith("JSON")) {
                // JSON类型转换为CLOB
                return "CLOB";
            } else if (cleanType.startsWith("GEOMETRY") || cleanType.startsWith("POINT") ||
                      cleanType.startsWith("LINESTRING") || cleanType.startsWith("POLYGON")) {
                // 几何类型转换为CLOB
                return "CLOB";
            } else if (cleanType.startsWith("DOUBLE")) {
                return "DOUBLE"; // 达梦支持DOUBLE
            } else if (cleanType.startsWith("FLOAT")) {
                return "FLOAT"; // 达梦支持FLOAT
            } else if (cleanType.startsWith("REAL")) {
                return "REAL"; // 达梦支持REAL
            } else if (cleanType.startsWith("NUMERIC") || cleanType.startsWith("NUMBER")) {
                return sourceType; // 达梦支持NUMERIC和NUMBER
            } else if (cleanType.startsWith("DECIMAL") || cleanType.startsWith("DEC")) {
                return sourceType; // 达梦支持DECIMAL
            } else if (cleanType.startsWith("VARCHAR2")) {
                return sourceType; // 达梦支持VARCHAR2
            } else if (cleanType.startsWith("NVARCHAR") || cleanType.startsWith("NCHAR")) {
                return sourceType; // 达梦支持NVARCHAR和NCHAR
            } else if (cleanType.startsWith("LONGVARCHAR")) {
                return "CLOB"; // LONGVARCHAR转换为CLOB
            }

            // 对于达梦到达梦的同步，直接返回清理后的类型
            return cleanTypeDefinition(sourceType);
        }

        return sourceType; // 其他情况保持原样
    }

    /**
     * 清理类型定义，移除MySQL特有的关键字
     */
    private String cleanTypeDefinition(String typeDefinition) {
        if (typeDefinition == null) {
            return typeDefinition;
        }

        String cleaned = typeDefinition.trim();

        // 移除MySQL特有的关键字
        cleaned = cleaned.replaceAll("\\s+UNSIGNED", "");
        cleaned = cleaned.replaceAll("\\s+ZEROFILL", "");
        cleaned = cleaned.replaceAll("\\s+AUTO_INCREMENT", "");
        cleaned = cleaned.replaceAll("\\s+BINARY", "");

        // 移除字符集和排序规则相关
        cleaned = cleaned.replaceAll("\\s+CHARACTER\\s+SET\\s+\\w+", "");
        cleaned = cleaned.replaceAll("\\s+COLLATE\\s+\\w+", "");

        // 移除注释
        cleaned = cleaned.replaceAll("\\s+COMMENT\\s+'[^']*'", "");
        cleaned = cleaned.replaceAll("\\s+COMMENT\\s+\"[^\"]*\"", "");

        return cleaned.trim();
    }

    /**
     * 判断是否为整数类型
     */
    private boolean isIntegerType(String columnType) {
        if (columnType == null) {
            return false;
        }

        String upperType = columnType.toUpperCase().trim();
        return upperType.equals("INT") || upperType.equals("INTEGER") ||
               upperType.equals("TINYINT") || upperType.equals("SMALLINT") ||
               upperType.equals("BIGINT");
    }
}